package pers.ree.demo.jvm;

import org.junit.Test;

public class ArrayMemory {

    public static void main(String[] args) {
        TestObject[] testObjectArray = new TestObject[10];

        for (int i=0; i<10; i++) {
            TestObject testObject = new TestObject();
            testObject.num = i;
            testObjectArray[i] = testObject;
        }

        // 仅这一句就能使垃圾回收器在执行时回收所有数组元素的内存
//        testObjectArray = null;

        // 不使用testObjectArray = null，执行以下循环也能使垃圾回收器执行时回收所有数组元素的内存
        for (int i=0; i<10; i++) {
            testObjectArray[i] = null;
        }

        // 对象testObject1=null，testObject1的内存也会被垃圾回收器回收
//        TestObject testObject1 = new TestObject();
//        testObject1.num = 100;
//        testObject1 = null;

        // 必须有这句，否则看不到finalize的执行结果
        System.gc();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    // 用于测试内存泄漏
    private TestObject testMemoryLeakObj;

    /**
     * 内存泄漏的测试用例
     */
    @Test
    public void testMemoryLeak() {
        testMemoryLeakObj = new TestObject();

        System.out.println("testMemoryLeak");

        // 如果没有这句，testMemoryLeakObj对象就不会被回收，导致内存泄漏
//        testMemoryLeakObj = null;

        System.gc();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class TestObject {

        private int num;

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println(num + ", TestObject finalize....");
        }
    }
}
